import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { In, Like, Repository } from 'typeorm';
import BaseCustom from '@main/entities/service/admin/base/base-custom.entity';
import { ApiException } from '@main/common/exceptions/api.exception';
import SysDictionary from '@main/entities/service/admin/sys/sys-dictionary.entity';
import { generateExcelFn } from '@main/excel';
import { SysOperationLogService } from '../../system/operationLog/operationLog.service';

@Injectable()
export class BaseCustomService {
  constructor(
    @InjectRepository(SysDictionary)
    private dictionaryRepository: Repository<SysDictionary>,

    @InjectRepository(BaseCustom)
    private customRepository: Repository<BaseCustom>,
    private operationLogService: SysOperationLogService
  ) {}

  async list() {
    return await this.customRepository.find();
  }

  /**
   * 罗列所有配置
   */
  async page(data) {
    const { pageSize, pageNum, entity = {} } = data;

    const { customName, customCode, ids = [] } = entity;

    const [dictionary] = await this.dictionaryRepository.findAndCount({
      where: {
        dictionaryTypeCode: Like(`%${'customer_type'}%`),
        languageType: Like(`%${'zh'}%`),
      },
    });

    const where = {
      customName: Like(`%${customName}%`),
      customCode: Like(`%${customCode}%`),
    };
    if (ids && ids.length) {
      where['id'] = In(ids);
    }

    let res = await this.customRepository.findAndCount({
      where,
      order: {
        updateTime: 'DESC',
      },
      take: pageSize,
      skip: (pageNum - 1) * pageSize,
    });

    res[0] &&
      res[0].length > 0 &&
      dictionary.length > 0 &&
      res[0].forEach((item) => {
        let dictionaryFind = dictionary.find((i) => {
          return item.customTypeId === i.dictionaryCode;
        });
        if (dictionaryFind) {
          item.customTypeName = dictionaryFind.dictionaryName;
        }
      });

    return res;
  }

  async export(dto, lang) {
    const [list] = await this.page(dto);

    if (!list || !(list as any).length) {
      throw new ApiException(10052);
    }

    const dataList = list;

    return await generateExcelFn(
      {
        sheetName: 'custom',
        mainHeaderList: [
          {
            label: 'customName',
          },
          {
            label: 'customCode',
          },
          {
            label: 'customShort',
          },
          {
            label: 'contacts',
          },
          {
            label: 'contactsTel',
          },
          {
            label: 'customTypeName',
          },
          {
            label: 'salesman',
          },
          {
            label: 'customHobby',
          },
          {
            label: 'customAddress',
          },
          {
            label: 'remark',
          },
        ],
        dataList,
      },
      lang
    );
  }

  /**
   * 新增
   */
  async add(data, user, mac, ip, syncHostSqlite) {
    const databaseOperationLogList = [];
    const custom = await this.customRepository.insert({
      ...data,
      createName: user.nickName,
      createUserName: user.userName,
      updateName: user.nickName,
      updateUserName: user.userName,
    });
    databaseOperationLogList.push({
      type: 'add',
      dataType: 'obj',
      database: 'BaseCustom',
      checkOnlyKeyList: [],
      data: custom,
      whereObj: null,
      remark: `BaseCustom表新增数据`,
    });
    await this.operationLogService.add(
      {
        type: 'add',
        msg: `客户管理模块新增客户`,
        databaseOperationLogList,
        remark: `新增客户${data.customName}`,
        mac,
        ip,
        syncHostSqlite: isNaN(Number(syncHostSqlite)) ? 0 : Number(syncHostSqlite),
      },
      user
    );
  }

  /**
   * 更新
   */
  async update(data, user, mac, ip, syncHostSqlite) {
    const databaseOperationLogList = [];
    await this.customRepository.update(
      { id: data.id },
      {
        customName: data.customName,
        customShort: data.customShort,
        contacts: data.contacts,
        contactsTel: data.contactsTel,
        customTypeId: data.customTypeId,
        salesman: data.salesman,
        customHobby: data.customHobby,
        customAddress: data.customAddress,
        remark: data.remark,
        updateName: user.nickName,
        updateUserName: user.userName,
      }
    );
    databaseOperationLogList.push({
      type: 'update',
      dataType: 'obj',
      database: 'BaseCustom',
      checkOnlyKeyList: [],
      data: {
        customName: data.customName,
        customShort: data.customShort,
        contacts: data.contacts,
        contactsTel: data.contactsTel,
        customTypeId: data.customTypeId,
        salesman: data.salesman,
        customHobby: data.customHobby,
        customAddress: data.customAddress,
        remark: data.remark,
        updateName: user.nickName,
        updateUserName: user.userName,
      },
      whereObj: { id: data.id },
      remark: `BaseCustom表更新客户信息`,
    });
    await this.operationLogService.add(
      {
        type: 'update',
        msg: `客户管理模块更新客户信息`,
        databaseOperationLogList,
        remark: `更新客户${data.customName}`,
        mac,
        ip,
        syncHostSqlite: isNaN(Number(syncHostSqlite)) ? 0 : Number(syncHostSqlite),
      },
      user
    );
  }

  /**
   * 删除
   */
  async delete(idList, user, mac, ip, syncHostSqlite) {
    const databaseOperationLogList = [];
    await this.customRepository.delete(idList);
    databaseOperationLogList.push({
      type: 'delete',
      dataType: 'array',
      database: 'BaseCustom',
      checkOnlyKeyList: [],
      data: null,
      whereObj: idList,
      remark: `BaseCustom表删除客户`,
    });
    await this.operationLogService.add(
      {
        type: 'delete',
        msg: `客户管理模块删除客户`,
        databaseOperationLogList,
        remark: `删除客户`,
        mac,
        ip,
        syncHostSqlite: isNaN(Number(syncHostSqlite)) ? 0 : Number(syncHostSqlite),
      },
      user
    );
  }

  async isExistKey(customCode: string) {
    const result = await this.customRepository.findOne({ where: { customCode } });

    if (result) {
      throw new ApiException(10022);
    }
  }

  async isExistCode(customCode: string) {
    const result = await this.customRepository.findOne({ where: { customCode } });
    return result;
  }
}
